AWS IoT Coreに権限管理を簡素化する機能が追加されました

AWS IoT Coreに権限管理を簡素化する機能が追加されました

Clock Icon2024.12.03

はじめに

コンサル部の神野です。2024/11/15にAWS IoT Coreで「モノと接続の関連付け」を使って権限管理を簡素化する機能がリリースされました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/11/aws-iot-core-capabilities-mqtt-messages-simplify-permission-management/

タイトルの響きだけ聞いてもピンと来なかったのですが、下記説明を見たら理解できました。

モノと接続の関連付けにより、クライアント ID がモノの名前と一致しない場合に、MQTT クライアントをレジストリのモノにマッピングできます。これにより、開発者は IoT ポリシーのレジストリ情報を活用し、デバイスのアクションをライフサイクルイベントに簡単に関連付け、カスタムコスト割り当てやリソース固有のログ記録などの既存の機能を利用できるようになります。それらの機能は、以前はクライアント ID とモノの名前を一致させるためにのみ利用可能でした。

今まではクライアントIDとモノの名前を一致させることで行えた機能が一致せずとも「モノと接続の関連付け」機能によって解決できるようになったアップデートな訳ですね。

どうやって関連付けを行うのか実際にやってみてご紹介したいと思います。

環境構築

まずは実行するために環境を作成します。
下記記事に従ってIoT Coreを試せる環境をTerraformで作成します。
コードレポジトリからpullしてそのコードを一部修正して実施する流れです。

環境作成記事

https://dev.classmethod.jp/articles/terraform-ec2-aws-iot-core/

コードレポジトリ

https://github.com/yuu551/template-iot-ec2

一部変更箇所

IoT Coreのポリシーを一部既存コードから変更します。
ポリシー変数を使って、モノに証明書がアタッチされている場合のみ接続できるように変更します。

iot.tf
# IoTポリシーを作成
# このポリシーは特定のトピックに対する操作を許可
resource "aws_iot_policy" "pubsub" {
  name = "PubSubToSpecificTopic"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        # 特定のクライアントの接続を許可
        Effect   = "Allow"
        Action   = ["iot:Connect"]
-		Resource = ["arn:aws:iot:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:client/${aws_iot_thing.example.name}"]
+       Resource = ["*"]
+       Condition = {
+         Bool = {
+           "iot:Connection.Thing.IsAttached": ["true"]
+         }
+       }
      },
      {
        # 特定のトピックへの発行と受信を許可
        Effect   = "Allow"
        Action   = ["iot:Publish", "iot:Receive"]
        Resource = ["arn:aws:iot:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:topic/my/test/topic"]
      },
      {
        # 特定のトピックフィルターへのサブスクリプションを許可
        Effect   = "Allow"
        Action   = ["iot:Subscribe"]
        Resource = ["arn:aws:iot:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:topicfilter/my/test/topic"]
      }
    ]
  })
}

実行

applyコマンドを実行して、環境に反映させます。

実行コマンド
terraform apply

作成が完了したらリソースを確認します。

確認

対象のモノとクライアントIDが一致していることを確認します。

IoT Coreに登録されているモノの名前

example-thingで作成されていますね。

CleanShot 2024-12-03 at 14.51.51@2x

クライアントIDの定義をしているコード

MQTTクライアントを作成する際に引数にクライアントIDを指定しています。
下記コードを見るとexample-thingとなっていますね。

iot_pubsub.py
# クライアントIDを引数に渡す
myMQTTClient = AWSIoTMQTTClient("example-thing")

AWS IoT Coreに登録されているモノの名前とクライアントIDがexample-thingで一致しているので、Session Managerで簡単なPubSub通信を実行してみて、疎通できる確認してみます。

Session Managerから疎通確認

ec2-userでログインしてiot_pubsub.pyを実行します。

実行コマンド
sudo su --login ec2-user

python3 iot_pubsub.py

CleanShot 2024-12-03 at 14.58.58@2x-3208549

CleanShot 2024-12-03 at 14.59.38@2x

問題なく疎通できていますね!

ここからクライアントIDを変更してみて、疎通に失敗するか確認してみます。
試しにClientIDをexample-thing-renameに変更します。

実行コマンド
sed -i 's/example-thing/example-thing-rename/g' iot_pubsub.py

CleanShot 2024-12-03 at 15.03.07@2x-3206809

この状態で再度iot_pubsub.pyを実行します。

実行コマンド
python3 iot_pubsub.py

CleanShot 2024-12-03 at 15.05.16@2x

クライアントIDとモノの名前が一致していないため、ポリシーに記載したモノのポリシー変数が解決できずタイムアウトが発生して接続に失敗しますね。
この状態でモノと接続の関連付けを行います。

「モノと接続の関連付け」を実施

IoT Coreの画面から関連付けを行います。
まずは、example-thingの詳細画面に移動し、証明書タブを開きます。

CleanShot 2024-12-03 at 15.06.14@2x

この状態で対象証明書にチェックを入れてアクション > 証明書をモノに独占的に関連付けるを押下します。

CleanShot 2024-12-03 at 15.11.27@2x

注意画面が出て、この証明書に紐づく他デバイスは全て紐付けが解除されると記載が表示されます。今回はこのデバイスしか証明書に紐づけていないので、特に気にせず接続の関連付けを独占的にするを押下します。

CleanShot 2024-12-03 at 15.14.15@2x

証明書と example-thing との独占的な関連付けに成功しましたと表示され、独占的プリンシパルが独占的と表示されていればOKです!

CleanShot 2024-12-03 at 15.14.48@2x

この状態で再度Session Managerからメッセージを送信してみます!

Session Managerから疎通確認

CleanShot 2024-12-03 at 15.19.20@2x
おおお、モノの名前とクライアントIDが一致していなくても送信できるようになりましたね!

その他

今回は「モノと接続の関連付け」使ってクライアントIDとモノの名前が異なっていてもモノのポリシー変数が利用できるようになりましたが、それ以外にも下記が実現できるようになりました。

公式ドキュメントの日本語訳より引用

https://docs.aws.amazon.com/iot/latest/developerguide/exclusive-thing.html

ライフサイクル イベント- ライフサイクル イベント (接続、切断、サブスクライブ、サブスクライブ解除など) でモノの名前を受け取ることができます。これにより、ルールなどでメッセージに含まれるモノの名前を処理できるようになります。詳細については、「ライフサイクル イベント」を参照してください。

リソース固有のログ記録- モノのグループに対してリソース固有のログ記録を設定し、定義されたモノのグループ内のすべてのモノに対して必要なログ記録設定を簡単に適用できます。詳細については、「AWS IoT でリソース固有のログ記録を設定する (CLI)」を参照してください。

コスト配分- コスト配分用のカスタム タグを使用して課金グループを作成し、これらのグループにアイテムを追加できます。詳細については、「課金グループ」を参照してください。

具体的にはライフサイクル イベント、リソース固有のログ記録、コスト配分も「モノと接続の関連付け」を使って、クライアントIDとモノの名前が異なる場合も利用できるようになります。

またライフサイクル イベント メッセージにモノの名前を含めたい場合は、逆に「モノと接続の関連付け」を行なっていないと含まれないと記載もあります。

ライフサイクル イベント メッセージにモノの名前を含めるには、IoT モノとクライアント接続に排他的関連付けが必要です。

おわりに

「モノの接続の関連付け」機能についていかがだったでしょうか。
今まではクライアントIDとモノの名前が一致していないと利用できない機能が、証明書とモノの紐付けを行うことで可能となりました。必要に応じて活用いただけるかと思います!

最後までご覧いただきありがとうございました!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.